#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>

pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
char *data;

#define READER_SERVER "READER"
#define SERVER "server_sock"

void *reader(void *p)
{
    int reader_svr_fd;
    struct sockaddr_un addr;

    unlink(READER_SERVER);
    bzero(&addr, sizeof(addr));
    addr.sun_family = AF_LOCAL;
    strcpy(addr.sun_path, READER_SERVER);

    socklen_t len = sizeof(addr);
    reader_svr_fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
    if (reader_svr_fd < 0)
    {
        perror("socket error");
        exit(-1);
    }
    if (bind(reader_svr_fd, (struct sockaddr *)&addr, len) < 0)
    {
        perror("bind error");
        close(reader_svr_fd);
        exit(-1);
    }
    printf("Bind is ok\n");

    for (;;)
    {
        char recv_buf[20] = "";
        recvfrom(reader_svr_fd, recv_buf, 50, 0, (struct sockaddr *)NULL, &len);
        if (strcmp(recv_buf, "OK") == 0)
        {
            pthread_mutex_lock(&lock);
            data = malloc(20);
            sprintf(data, "hello world");
            pthread_mutex_unlock(&lock);
            pthread_cond_signal(&has_product);
        }

        else
        {
            printf("reader recv error\n");
            exit(-1);
        }
    }
}

int SendCmd(const char *cmd)
{
    int sockfd = 0;
    struct sockaddr_un serveraddr;

    bzero(&serveraddr, sizeof(serveraddr));

    serveraddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path, SERVER);

    socklen_t len = sizeof(serveraddr);
    sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        perror("socket error");
        exit(-1);
    }

    char send_buf[20] = "";
    sprintf(send_buf, "%s", cmd);
    sendto(sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&serveraddr, len);
    printf("send ok and wait \n");

    struct timespec timeout;
    timeout.tv_sec = time(0) + 10;
    timeout.tv_nsec = 0;
    pthread_mutex_lock(&lock);
    int ret = pthread_cond_timedwait(&has_product, &lock, &timeout);
    if (data != NULL)
    {
        printf("%s\n", data);
        free(data);
    }

    pthread_mutex_unlock(&lock);
    if (ret == 0)
        return 1;
    else
    {
        printf("timeout condition sig %d\n", ret);
        return 0;
    }
}

int main(int argc, char *argv[])
{
    pthread_t pid;
    pthread_create(&pid, NULL, reader, NULL);
    sleep(1);
    int ret = SendCmd("hello");
    if (ret == 1)
        printf("元旦快乐\n");

    pthread_cancel(pid);
    pthread_join(pid, NULL);
    return 0;
}